package gui;
import java.awt.datatransfer.StringSelection;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Vector;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

import main.Driver;
import main.USBManager;
import main.WAVPlayer;
import net.miginfocom.swing.MigLayout;


public class MainFrame extends JFrame implements DragSourceListener ,DragGestureListener {

	/**Panel which holds calendar*/
	private static CalendarPanel calendarPanel ;

	/**Wave player to play selected wave content*/
	private WAVPlayer wavPlayer;

	private JPanel mainPanel;

	private File selectedUSBFile;

	private DragSource ds;

	private Vector<File> usbFiles = new Vector<File>();

	private JTable usbFilesListTable;


	/**
	 * Create the frame.
	 */
	public MainFrame() { 

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 522, 363);
		mainPanel = new JPanel();
		mainPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(mainPanel);
		mainPanel.setLayout(new MigLayout("", "[89px,grow][246px,grow][89px]", "[23px][grow][20][20]"));
		setVisible(true);

		usbFilesListTable = new JTable(new TableModel() {

			@Override
			public void setValueAt(Object arg0, int arg1, int arg2) {
		System.out.println(usbFiles.size());
				try {
					USBManager.renameFile((String)getValueAt(arg1, arg2), (String)arg0);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				usbFiles.remove(USBManager.nameToFile((String)getValueAt(arg1, arg2)));
				
				System.out.println(usbFiles.size());
				usbFiles.add(USBManager.nameToFile((String)arg0) );
				selectedUSBFile = USBManager.nameToFile((String)arg0);	
				System.out.println(usbFiles.size());
  	usbFilesListTable.repaint();
			}

			@Override
			public void removeTableModelListener(TableModelListener arg0) {}

			@Override
			public Object getValueAt(int arg0, int arg1) {
				switch (arg1){ 
				case 0:
				return  usbFiles.get(arg0).getName();
				case 1:
					SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
					Calendar t= Calendar.getInstance();
					t.setTimeInMillis(usbFiles.get(arg0).lastModified());
					
					return  formatter.format(t.getTime()).toString();
 
					case 2: 
					try {
						int tel = (int) getWavLength(usbFiles.get(arg0).getAbsolutePath());
						String ret  = tel/60 + " dk "  + tel % 60 + " sn";
						return ret;
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					default:
								return " ";
				}
				
			}

			@Override
			public int getRowCount() {
				return usbFiles.size();
			}

			@Override
			public String getColumnName(int arg0) { 
				return "";
			}

			@Override
			public int getColumnCount() {
				return 3;
			}

			@Override
			public Class<?> getColumnClass(int arg0) {
				return getValueAt(0, arg0).getClass();
			}

			@Override
			public void addTableModelListener(TableModelListener arg0) {}

			@Override
			public boolean isCellEditable(int rowIndex, int columnIndex) {
				return true;
			}
		});


		usbFilesListTable.getSelectionModel();
		usbFilesListTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		usbFilesListTable.setDragEnabled(true);
		usbFilesListTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

			@Override
			public void valueChanged(ListSelectionEvent arg0) {
				selectedUSBFile = usbFiles.get(usbFilesListTable.getSelectedRow()) ;
			}
		});
		 
		
		ds = new DragSource();
		DragGestureRecognizer dgr = ds.createDefaultDragGestureRecognizer(usbFilesListTable,
				DnDConstants.ACTION_COPY, this);
		setVisible(true);

		JScrollPane scrollPane = new JScrollPane(usbFilesListTable);

		mainPanel.add(scrollPane, "cell 0 1");

		calendarPanel = new CalendarPanel();
		mainPanel.add(calendarPanel, "cell 1 1 2 1,grow");
		
		ds =  new DragSource();

		JButton btnNewButton = new JButton("Play Selected");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (wavPlayer != null) {
					wavPlayer.stop();
				}
			}
		});
		mainPanel.add(btnNewButton, "flowx,cell 0 2");

		JButton btnNewButton_2 = new JButton("New button");
		btnNewButton_2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(wavPlayer != null)
					wavPlayer.stop();
				try {

					wavPlayer = new WAVPlayer(selectedUSBFile );
					wavPlayer.play();
				} catch (UnsupportedAudioFileException e) {
					// TODO Auto-generated catch block				e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (LineUnavailableException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		mainPanel.add(btnNewButton_2, "cell 0 2");

		JButton btnNewButton_1 = new JButton("Previous Month");
		btnNewButton_1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				calendarPanel.decrementMonth();
				repaint();
			}
		});
		mainPanel.add(btnNewButton_1, "flowx,cell 1 2");

	
		JButton btnNewButton_3 = new JButton("New button");
		btnNewButton_3.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				calendarPanel.incrementMonth();
				repaint();

			}
		});
		mainPanel.add(btnNewButton_3, "cell 1 2");
		
		
		JSlider slider = new JSlider();
		slider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent arg0) {
				JSlider slider = (JSlider) arg0.getSource();
				if(wavPlayer != null) 
					wavPlayer.seek(slider.getValue());
			}
		});
		mainPanel.add(slider, "cell 0 3");

	}

	
	public void dragGestureRecognized(DragGestureEvent dge) {
		ds.startDrag(dge, DragSource.DefaultCopyDrop,new StringSelection(""), this);
	} 

	public void dragEnter(DragSourceDragEvent dsde) {}
	public void dragExit(DragSourceEvent dse) {}
	public void dragOver(DragSourceDragEvent dsde) {}
	public void dropActionChanged(DragSourceDragEvent arg0) {}
	
	
	public void dragDropEnd(DragSourceDropEvent dsde) {

		final int mouseX = dsde.getX() - getX() - 7;
		final int mouseY = dsde.getY() - getY() - 30;
	 
		if(mouseX > calendarPanel.getX() && mouseX < calendarPanel.getX() + calendarPanel.getWidth() 
		&& mouseY > calendarPanel.getY() && mouseY < calendarPanel.getY() + calendarPanel.getHeight()) {
		
			SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
				public Void doInBackground() {
					try {
						Driver.processFile(selectedUSBFile,calendarPanel.drop(mouseX,mouseY));
					} catch (Exception e) {					 
						e.printStackTrace();
					} 
					return null;
				}
				
			};
				worker.execute();
				 
		}
	}

	public  void update() {
		
		this.repaint();
		calendarPanel.revalidate();
		calendarPanel.repaint();		
	}
 
	public void updateUSBList() {

		usbFiles.clear();

		for(File f : USBManager.getAllFiles()) {
			usbFiles.add(f );
		} 
		usbFilesListTable.updateUI();
	}
	 public static double getWavLength(String s) throws UnsupportedAudioFileException, IOException
	 {   File file = new File(s);
		    AudioInputStream stream = null;
 
		        stream = AudioSystem.getAudioInputStream(file);

		        AudioFormat format = stream.getFormat();

		        return file.length() / format.getSampleRate() / (format.getSampleSizeInBits() / 8.0) / format.getChannels();
	 
		}

}
